﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Diagnostics;
using Tracy.CoreLib.Data;
using Tracy.CoreLib;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections;

namespace Tracy.Agent.DownloaderAdapter
{
    public class EmuleAdapter :AbstractDownloaderAdapter, IDownloaderAdapter
    {
        public event EventHandler<EventArgsWithData> OnException;
        private string hostPath = null;
        public override string HostPath
        {
            get
            {
                if (hostPath == null)
                {
                    RegistryKey regdir = Registry.CurrentUser.OpenSubKey("SOFTWARE", false);
                    regdir = regdir.OpenSubKey("easyMule", false);
                    hostPath = regdir.GetValue("InstallPath").ToString() + regdir.GetValue("FileName").ToString();
                }
                return hostPath;

            }
        }

        public override string HostProcessName
        {
            get
            {
                return Constants.CONST_APPLICATION_PROCESS_EMULE;
            }
        }

        private static ReaderWriterLock rwlock = new ReaderWriterLock();

        private Thread threadSendTask;
        private Thread threadAutoDialogHandler;

        private Queue<ResourceItem> cachedTasks;

        public Queue<ResourceItem> CachedTasks
        {
            get { if (cachedTasks == null)cachedTasks = new Queue<ResourceItem>(); return cachedTasks; }
            set { cachedTasks = value; }
        }

        public bool AddToDownload(Tracy.CoreLib.Data.ResourceItem item)
        {
            rwlock.AcquireWriterLock(10);
            CachedTasks.Enqueue(item);
            rwlock.ReleaseWriterLock();
            if (threadSendTask == null || threadSendTask.ThreadState == System.Threading.ThreadState.Stopped)
            {
                threadSendTask = new Thread(new ThreadStart(SendTask));
                threadSendTask.Start();
            }
            return true;
        }

        private void AutoDialogHandler()
        {
            int dialoghWnd = 0;
            int retry = 0;
            const int MAX_RETRY_TIMES = 300;  //3秒超时
            //处理重复任务对话框
            do
            {
                System.Threading.Thread.Sleep(10);
                dialoghWnd = FindWindow("#32770", "电驴");
                if (dialoghWnd != 0)
                {
                    System.Threading.Thread.Sleep(100);

                    //发现重复任务则不添加
                    PostMessage(dialoghWnd, WM_KEYDOWN, 27, 0);
                    retry = 0;
                }
                retry++;
            } while (retry <= MAX_RETRY_TIMES && !killThreadFlag);
        }

        private void SendTask()
        {
            try
            {
                //等待缓存队列平静
                int currentCount = 0;
                rwlock.AcquireReaderLock(10);
                currentCount = CachedTasks.Count;
                rwlock.ReleaseReaderLock();
                if (currentCount > 0)
                {
                    const int MAX_WAIT_TIMES_SENDTASK = 10;
                    int wait = 0;
                    bool flag = false;
                    while (wait < MAX_WAIT_TIMES_SENDTASK)
                    {
                        Thread.Sleep(100);
                        rwlock.AcquireReaderLock(10);
                        flag = (currentCount == CachedTasks.Count);
                        currentCount = CachedTasks.Count;
                        rwlock.ReleaseReaderLock();
                        if (flag) break;
                        if (killThreadFlag) return;
                        wait++;
                    }

                    //取出缓存队列的内容，按Folder排序
                    ResourceItem item;
                    SortedList<string, ResourceItem> tasksToSend = new SortedList<string, ResourceItem>(SortedByStringComparer.Default);
                    rwlock.AcquireReaderLock(10);
                    while (CachedTasks.Count > 0)
                    {
                        item = CachedTasks.Dequeue();
                        tasksToSend.Add(item.Folder, item);
                    }
                    rwlock.ReleaseReaderLock();

                    if (tasksToSend.Count > 0)
                    {
                        //按Folder分组向Emule添加任务
                        string currentFolder = tasksToSend.Values[0].Folder;
                        for (int i = 0; i < tasksToSend.Count; i++)
                        {
                            item = tasksToSend.Values[i];
                            //向Emule添加任务
                            Process.Start(HostPath, "\"" + item.Link + "\"");
                            if (currentFolder != item.Folder || i == tasksToSend.Count - 1)
                            {
                                ConfirmTask(currentFolder);
                                currentFolder = item.Folder;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                OnException(this, new EventArgsWithData(e));
            }
        }

        private void ConfirmTask(string folder)
        {

            const int MAX_RETRY_TIMES_ADDTASK = 1000;  //10秒超时
            const int MAX_RETRY_TIMES_ADDEDTASK = 300;  //3秒超时
            //查找添加任务对话框
            string emuleDialogTitle = "添加任务";

            int dialoghWnd = 0;
            int retry = 0;

            do
            {
                System.Threading.Thread.Sleep(10);
                dialoghWnd = FindWindow("#32770", emuleDialogTitle);
                retry++;
                if (retry >= MAX_RETRY_TIMES_ADDTASK) throw new Exception("找不到“" + emuleDialogTitle + "”对话框"); //超时退出
                if (killThreadFlag) return;
            } while (dialoghWnd == 0);

            //输入地址
            int texthWnd = FindWindowEx(dialoghWnd, 0, "ComboBox", null);
            SendMessage(texthWnd, WM_SETTEXT, 0, folder);

            //发送回车
            PostMessage(dialoghWnd, WM_KEYDOWN, 13, 0);

            if (threadAutoDialogHandler == null || threadAutoDialogHandler.ThreadState == System.Threading.ThreadState.Stopped)
            {
                threadAutoDialogHandler = new Thread(new ThreadStart(AutoDialogHandler));
                threadAutoDialogHandler.Start();
            }

            //等待窗口关闭
            retry = 0;
            do
            {
                System.Threading.Thread.Sleep(10);
                dialoghWnd = FindWindow("#32770", emuleDialogTitle);
                retry++;
                if (retry >= MAX_RETRY_TIMES_ADDEDTASK) throw new Exception("无法处理“" + emuleDialogTitle + "”对话框"); //超时退出
                if (killThreadFlag) return;
            } while (dialoghWnd != 0);


        }
        
    }
}
